home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / zipfile.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  19KB  |  624 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''Read and write ZIP files.'''
  5. import struct
  6. import os
  7. import time
  8. import binascii
  9.  
  10. try:
  11.     import zlib
  12. except ImportError:
  13.     zlib = None
  14.  
  15. __all__ = [
  16.     'BadZipfile',
  17.     'error',
  18.     'ZIP_STORED',
  19.     'ZIP_DEFLATED',
  20.     'is_zipfile',
  21.     'ZipInfo',
  22.     'ZipFile',
  23.     'PyZipFile']
  24.  
  25. class BadZipfile(Exception):
  26.     pass
  27.  
  28. error = BadZipfile
  29. ZIP_STORED = 0
  30. ZIP_DEFLATED = 8
  31. structEndArchive = '<4s4H2lH'
  32. stringEndArchive = 'PK\x05\x06'
  33. structCentralDir = '<4s4B4HlLL5HLl'
  34. stringCentralDir = 'PK\x01\x02'
  35. structFileHeader = '<4s2B4HlLL2H'
  36. stringFileHeader = 'PK\x03\x04'
  37. _CD_SIGNATURE = 0
  38. _CD_CREATE_VERSION = 1
  39. _CD_CREATE_SYSTEM = 2
  40. _CD_EXTRACT_VERSION = 3
  41. _CD_EXTRACT_SYSTEM = 4
  42. _CD_FLAG_BITS = 5
  43. _CD_COMPRESS_TYPE = 6
  44. _CD_TIME = 7
  45. _CD_DATE = 8
  46. _CD_CRC = 9
  47. _CD_COMPRESSED_SIZE = 10
  48. _CD_UNCOMPRESSED_SIZE = 11
  49. _CD_FILENAME_LENGTH = 12
  50. _CD_EXTRA_FIELD_LENGTH = 13
  51. _CD_COMMENT_LENGTH = 14
  52. _CD_DISK_NUMBER_START = 15
  53. _CD_INTERNAL_FILE_ATTRIBUTES = 16
  54. _CD_EXTERNAL_FILE_ATTRIBUTES = 17
  55. _CD_LOCAL_HEADER_OFFSET = 18
  56. _FH_SIGNATURE = 0
  57. _FH_EXTRACT_VERSION = 1
  58. _FH_EXTRACT_SYSTEM = 2
  59. _FH_GENERAL_PURPOSE_FLAG_BITS = 3
  60. _FH_COMPRESSION_METHOD = 4
  61. _FH_LAST_MOD_TIME = 5
  62. _FH_LAST_MOD_DATE = 6
  63. _FH_CRC = 7
  64. _FH_COMPRESSED_SIZE = 8
  65. _FH_UNCOMPRESSED_SIZE = 9
  66. _FH_FILENAME_LENGTH = 10
  67. _FH_EXTRA_FIELD_LENGTH = 11
  68.  
  69. def is_zipfile(filename):
  70.     '''Quickly see if file is a ZIP file by checking the magic number.'''
  71.     
  72.     try:
  73.         fpin = open(filename, 'rb')
  74.         endrec = _EndRecData(fpin)
  75.         fpin.close()
  76.         if endrec:
  77.             return True
  78.     except IOError:
  79.         pass
  80.  
  81.     return False
  82.  
  83.  
  84. def _EndRecData(fpin):
  85.     '''Return data from the "End of Central Directory" record, or None.
  86.  
  87.     The data is a list of the nine items in the ZIP "End of central dir"
  88.     record followed by a tenth item, the file seek offset of this record.'''
  89.     fpin.seek(-22, 2)
  90.     filesize = fpin.tell() + 22
  91.     data = fpin.read()
  92.     if data[0:4] == stringEndArchive and data[-2:] == '\x00\x00':
  93.         endrec = struct.unpack(structEndArchive, data)
  94.         endrec = list(endrec)
  95.         endrec.append('')
  96.         endrec.append(filesize - 22)
  97.         return endrec
  98.     
  99.     END_BLOCK = min(filesize, 1024 * 4)
  100.     fpin.seek(filesize - END_BLOCK, 0)
  101.     data = fpin.read()
  102.     start = data.rfind(stringEndArchive)
  103.     if start >= 0:
  104.         endrec = struct.unpack(structEndArchive, data[start:start + 22])
  105.         endrec = list(endrec)
  106.         comment = data[start + 22:]
  107.         if endrec[7] == len(comment):
  108.             endrec.append(comment)
  109.             endrec.append((filesize - END_BLOCK) + start)
  110.             return endrec
  111.         
  112.     
  113.  
  114.  
  115. class ZipInfo:
  116.     '''Class with attributes describing each file in the ZIP archive.'''
  117.     
  118.     def __init__(self, filename = 'NoName', date_time = (1980, 1, 1, 0, 0, 0)):
  119.         self.orig_filename = filename
  120.         null_byte = filename.find(chr(0))
  121.         if null_byte >= 0:
  122.             filename = filename[0:null_byte]
  123.         
  124.         if os.sep != '/':
  125.             filename = filename.replace(os.sep, '/')
  126.         
  127.         self.filename = filename
  128.         self.date_time = date_time
  129.         self.compress_type = ZIP_STORED
  130.         self.comment = ''
  131.         self.extra = ''
  132.         self.create_system = 0
  133.         self.create_version = 20
  134.         self.extract_version = 20
  135.         self.reserved = 0
  136.         self.flag_bits = 0
  137.         self.volume = 0
  138.         self.internal_attr = 0
  139.         self.external_attr = 0
  140.  
  141.     
  142.     def FileHeader(self):
  143.         '''Return the per-file header as a string.'''
  144.         dt = self.date_time
  145.         dosdate = dt[0] - 1980 << 9 | dt[1] << 5 | dt[2]
  146.         dostime = dt[3] << 11 | dt[4] << 5 | dt[5] // 2
  147.         if self.flag_bits & 8:
  148.             CRC = compress_size = file_size = 0
  149.         else:
  150.             CRC = self.CRC
  151.             compress_size = self.compress_size
  152.             file_size = self.file_size
  153.         header = struct.pack(structFileHeader, stringFileHeader, self.extract_version, self.reserved, self.flag_bits, self.compress_type, dostime, dosdate, CRC, compress_size, file_size, len(self.filename), len(self.extra))
  154.         return header + self.filename + self.extra
  155.  
  156.  
  157.  
  158. class ZipFile:
  159.     ''' Class with methods to open, read, write, close, list zip files.
  160.  
  161.     z = ZipFile(file, mode="r", compression=ZIP_STORED)
  162.  
  163.     file: Either the path to the file, or a file-like object.
  164.           If it is a path, the file will be opened and closed by ZipFile.
  165.     mode: The mode can be either read "r", write "w" or append "a".
  166.     compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib).
  167.     '''
  168.     fp = None
  169.     
  170.     def __init__(self, file, mode = 'r', compression = ZIP_STORED):
  171.         '''Open the ZIP file with mode read "r", write "w" or append "a".'''
  172.         if compression == ZIP_STORED:
  173.             pass
  174.         elif compression == ZIP_DEFLATED:
  175.             if not zlib:
  176.                 raise RuntimeError, 'Compression requires the (missing) zlib module'
  177.             
  178.         else:
  179.             raise RuntimeError, 'That compression method is not supported'
  180.         self.debug = 0
  181.         self.NameToInfo = { }
  182.         self.filelist = []
  183.         self.compression = compression
  184.         self.mode = key = mode.replace('b', '')[0]
  185.         if isinstance(file, basestring):
  186.             self._filePassed = 0
  187.             self.filename = file
  188.             modeDict = {
  189.                 'r': 'rb',
  190.                 'w': 'wb',
  191.                 'a': 'r+b' }
  192.             self.fp = open(file, modeDict[mode])
  193.         else:
  194.             self._filePassed = 1
  195.             self.fp = file
  196.             self.filename = getattr(file, 'name', None)
  197.         if key == 'r':
  198.             self._GetContents()
  199.         elif key == 'w':
  200.             pass
  201.         elif key == 'a':
  202.             
  203.             try:
  204.                 self._RealGetContents()
  205.                 self.fp.seek(self.start_dir, 0)
  206.             except BadZipfile:
  207.                 self.fp.seek(0, 2)
  208.             except:
  209.                 None<EXCEPTION MATCH>BadZipfile
  210.             
  211.  
  212.         None<EXCEPTION MATCH>BadZipfile
  213.         if not self._filePassed:
  214.             self.fp.close()
  215.             self.fp = None
  216.         
  217.         raise RuntimeError, 'Mode must be "r", "w" or "a"'
  218.  
  219.     
  220.     def _GetContents(self):
  221.         '''Read the directory, making sure we close the file if the format
  222.         is bad.'''
  223.         
  224.         try:
  225.             self._RealGetContents()
  226.         except BadZipfile:
  227.             if not self._filePassed:
  228.                 self.fp.close()
  229.                 self.fp = None
  230.             
  231.             raise 
  232.  
  233.  
  234.     
  235.     def _RealGetContents(self):
  236.         '''Read in the table of contents for the ZIP file.'''
  237.         fp = self.fp
  238.         endrec = _EndRecData(fp)
  239.         if not endrec:
  240.             raise BadZipfile, 'File is not a zip file'
  241.         
  242.         if self.debug > 1:
  243.             print endrec
  244.         
  245.         size_cd = endrec[5]
  246.         offset_cd = endrec[6]
  247.         self.comment = endrec[8]
  248.         x = endrec[9] - size_cd
  249.         concat = x - offset_cd
  250.         if self.debug > 2:
  251.             print 'given, inferred, offset', offset_cd, x, concat
  252.         
  253.         self.start_dir = offset_cd + concat
  254.         fp.seek(self.start_dir, 0)
  255.         total = 0
  256.         while total < size_cd:
  257.             centdir = fp.read(46)
  258.             total = total + 46
  259.             if centdir[0:4] != stringCentralDir:
  260.                 raise BadZipfile, 'Bad magic number for central directory'
  261.             
  262.             centdir = struct.unpack(structCentralDir, centdir)
  263.             if self.debug > 2:
  264.                 print centdir
  265.             
  266.             filename = fp.read(centdir[_CD_FILENAME_LENGTH])
  267.             x = ZipInfo(filename)
  268.             x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
  269.             x.comment = fp.read(centdir[_CD_COMMENT_LENGTH])
  270.             total = total + centdir[_CD_FILENAME_LENGTH] + centdir[_CD_EXTRA_FIELD_LENGTH] + centdir[_CD_COMMENT_LENGTH]
  271.             x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET] + concat
  272.             (x.create_version, x.create_system, x.extract_version, x.reserved, x.flag_bits, x.compress_type, t, d, x.CRC, x.compress_size, x.file_size) = centdir[1:12]
  273.             (x.volume, x.internal_attr, x.external_attr) = centdir[15:18]
  274.             x.date_time = ((d >> 9) + 1980, d >> 5 & 15, d & 31, t >> 11, t >> 5 & 63, (t & 31) * 2)
  275.             self.filelist.append(x)
  276.             self.NameToInfo[x.filename] = x
  277.             if self.debug > 2:
  278.                 print 'total', total
  279.                 continue
  280.         for data in self.filelist:
  281.             fp.seek(data.header_offset, 0)
  282.             fheader = fp.read(30)
  283.             if fheader[0:4] != stringFileHeader:
  284.                 raise BadZipfile, 'Bad magic number for file header'
  285.             
  286.             fheader = struct.unpack(structFileHeader, fheader)
  287.             data.file_offset = data.header_offset + 30 + fheader[_FH_FILENAME_LENGTH] + fheader[_FH_EXTRA_FIELD_LENGTH]
  288.             fname = fp.read(fheader[_FH_FILENAME_LENGTH])
  289.             if fname != data.orig_filename:
  290.                 raise RuntimeError, 'File name in directory "%s" and header "%s" differ.' % (data.orig_filename, fname)
  291.                 continue
  292.         
  293.  
  294.     
  295.     def namelist(self):
  296.         '''Return a list of file names in the archive.'''
  297.         l = []
  298.         for data in self.filelist:
  299.             l.append(data.filename)
  300.         
  301.         return l
  302.  
  303.     
  304.     def infolist(self):
  305.         '''Return a list of class ZipInfo instances for files in the
  306.         archive.'''
  307.         return self.filelist
  308.  
  309.     
  310.     def printdir(self):
  311.         '''Print a table of contents for the zip file.'''
  312.         print '%-46s %19s %12s' % ('File Name', 'Modified    ', 'Size')
  313.         for zinfo in self.filelist:
  314.             date = '%d-%02d-%02d %02d:%02d:%02d' % zinfo.date_time
  315.             print '%-46s %s %12d' % (zinfo.filename, date, zinfo.file_size)
  316.         
  317.  
  318.     
  319.     def testzip(self):
  320.         '''Read all the files and check the CRC.'''
  321.         for zinfo in self.filelist:
  322.             
  323.             try:
  324.                 self.read(zinfo.filename)
  325.             continue
  326.             except BadZipfile:
  327.                 return zinfo.filename
  328.                 continue
  329.             
  330.  
  331.         
  332.  
  333.     
  334.     def getinfo(self, name):
  335.         """Return the instance of ZipInfo given 'name'."""
  336.         return self.NameToInfo[name]
  337.  
  338.     
  339.     def read(self, name):
  340.         '''Return file bytes (as a string) for name.'''
  341.         if self.mode not in ('r', 'a'):
  342.             raise RuntimeError, 'read() requires mode "r" or "a"'
  343.         
  344.         if not self.fp:
  345.             raise RuntimeError, 'Attempt to read ZIP archive that was already closed'
  346.         
  347.         zinfo = self.getinfo(name)
  348.         filepos = self.fp.tell()
  349.         self.fp.seek(zinfo.file_offset, 0)
  350.         bytes = self.fp.read(zinfo.compress_size)
  351.         self.fp.seek(filepos, 0)
  352.         if zinfo.compress_type == ZIP_STORED:
  353.             pass
  354.         elif zinfo.compress_type == ZIP_DEFLATED:
  355.             if not zlib:
  356.                 raise RuntimeError, 'De-compression requires the (missing) zlib module'
  357.             
  358.             dc = zlib.decompressobj(-15)
  359.             bytes = dc.decompress(bytes)
  360.             ex = dc.decompress('Z') + dc.flush()
  361.             if ex:
  362.                 bytes = bytes + ex
  363.             
  364.         else:
  365.             raise BadZipfile, 'Unsupported compression method %d for file %s' % (zinfo.compress_type, name)
  366.         crc = binascii.crc32(bytes)
  367.         if crc != zinfo.CRC:
  368.             raise BadZipfile, 'Bad CRC-32 for file %s' % name
  369.         
  370.         return bytes
  371.  
  372.     
  373.     def _writecheck(self, zinfo):
  374.         '''Check for errors before writing a file to the archive.'''
  375.         if zinfo.filename in self.NameToInfo:
  376.             if self.debug:
  377.                 print 'Duplicate name:', zinfo.filename
  378.             
  379.         
  380.         if self.mode not in ('w', 'a'):
  381.             raise RuntimeError, 'write() requires mode "w" or "a"'
  382.         
  383.         if not self.fp:
  384.             raise RuntimeError, 'Attempt to write ZIP archive that was already closed'
  385.         
  386.         if zinfo.compress_type == ZIP_DEFLATED and not zlib:
  387.             raise RuntimeError, 'Compression requires the (missing) zlib module'
  388.         
  389.         if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED):
  390.             raise RuntimeError, 'That compression method is not supported'
  391.         
  392.  
  393.     
  394.     def write(self, filename, arcname = None, compress_type = None):
  395.         '''Put the bytes from filename into the archive under the name
  396.         arcname.'''
  397.         st = os.stat(filename)
  398.         mtime = time.localtime(st.st_mtime)
  399.         date_time = mtime[0:6]
  400.         if arcname is None:
  401.             zinfo = ZipInfo(filename, date_time)
  402.         else:
  403.             zinfo = ZipInfo(arcname, date_time)
  404.         zinfo.external_attr = (st[0] & 65535) << 0x10L
  405.         if compress_type is None:
  406.             zinfo.compress_type = self.compression
  407.         else:
  408.             zinfo.compress_type = compress_type
  409.         self._writecheck(zinfo)
  410.         fp = open(filename, 'rb')
  411.         zinfo.flag_bits = 0
  412.         zinfo.header_offset = self.fp.tell()
  413.         zinfo.CRC = CRC = 0
  414.         zinfo.compress_size = compress_size = 0
  415.         zinfo.file_size = file_size = 0
  416.         self.fp.write(zinfo.FileHeader())
  417.         zinfo.file_offset = self.fp.tell()
  418.         if zinfo.compress_type == ZIP_DEFLATED:
  419.             cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, -15)
  420.         else:
  421.             cmpr = None
  422.         while None:
  423.             buf = fp.read(1024 * 8)
  424.             if not buf:
  425.                 break
  426.             
  427.             file_size = file_size + len(buf)
  428.             CRC = binascii.crc32(buf, CRC)
  429.             if cmpr:
  430.                 buf = cmpr.compress(buf)
  431.                 compress_size = compress_size + len(buf)
  432.             
  433.         fp.close()
  434.         if cmpr:
  435.             buf = cmpr.flush()
  436.             compress_size = compress_size + len(buf)
  437.             self.fp.write(buf)
  438.             zinfo.compress_size = compress_size
  439.         else:
  440.             zinfo.compress_size = file_size
  441.         zinfo.CRC = CRC
  442.         zinfo.file_size = file_size
  443.         position = self.fp.tell()
  444.         self.fp.seek(zinfo.header_offset + 14, 0)
  445.         self.fp.write(struct.pack('<lLL', zinfo.CRC, zinfo.compress_size, zinfo.file_size))
  446.         self.fp.seek(position, 0)
  447.         self.filelist.append(zinfo)
  448.         self.NameToInfo[zinfo.filename] = zinfo
  449.  
  450.     
  451.     def writestr(self, zinfo_or_arcname, bytes):
  452.         """Write a file into the archive.  The contents is the string
  453.         'bytes'.  'zinfo_or_arcname' is either a ZipInfo instance or
  454.         the name of the file in the archive."""
  455.         if not isinstance(zinfo_or_arcname, ZipInfo):
  456.             zinfo = ZipInfo(filename = zinfo_or_arcname, date_time = time.localtime(time.time()))
  457.             zinfo.compress_type = self.compression
  458.         else:
  459.             zinfo = zinfo_or_arcname
  460.         self._writecheck(zinfo)
  461.         zinfo.file_size = len(bytes)
  462.         zinfo.CRC = binascii.crc32(bytes)
  463.         if zinfo.compress_type == ZIP_DEFLATED:
  464.             co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, -15)
  465.             bytes = co.compress(bytes) + co.flush()
  466.             zinfo.compress_size = len(bytes)
  467.         else:
  468.             zinfo.compress_size = zinfo.file_size
  469.         zinfo.header_offset = self.fp.tell()
  470.         self.fp.write(zinfo.FileHeader())
  471.         zinfo.file_offset = self.fp.tell()
  472.         self.fp.write(bytes)
  473.         if zinfo.flag_bits & 8:
  474.             self.fp.write(struct.pack('<lLL', zinfo.CRC, zinfo.compress_size, zinfo.file_size))
  475.         
  476.         self.filelist.append(zinfo)
  477.         self.NameToInfo[zinfo.filename] = zinfo
  478.  
  479.     
  480.     def __del__(self):
  481.         '''Call the "close()" method in case the user forgot.'''
  482.         self.close()
  483.  
  484.     
  485.     def close(self):
  486.         '''Close the file, and for mode "w" and "a" write the ending
  487.         records.'''
  488.         if self.fp is None:
  489.             return None
  490.         
  491.         if self.mode in ('w', 'a'):
  492.             count = 0
  493.             pos1 = self.fp.tell()
  494.             for zinfo in self.filelist:
  495.                 count = count + 1
  496.                 dt = zinfo.date_time
  497.                 dosdate = dt[0] - 1980 << 9 | dt[1] << 5 | dt[2]
  498.                 dostime = dt[3] << 11 | dt[4] << 5 | dt[5] // 2
  499.                 centdir = struct.pack(structCentralDir, stringCentralDir, zinfo.create_version, zinfo.create_system, zinfo.extract_version, zinfo.reserved, zinfo.flag_bits, zinfo.compress_type, dostime, dosdate, zinfo.CRC, zinfo.compress_size, zinfo.file_size, len(zinfo.filename), len(zinfo.extra), len(zinfo.comment), 0, zinfo.internal_attr, zinfo.external_attr, zinfo.header_offset)
  500.                 self.fp.write(centdir)
  501.                 self.fp.write(zinfo.filename)
  502.                 self.fp.write(zinfo.extra)
  503.                 self.fp.write(zinfo.comment)
  504.             
  505.             pos2 = self.fp.tell()
  506.             endrec = struct.pack(structEndArchive, stringEndArchive, 0, 0, count, count, pos2 - pos1, pos1, 0)
  507.             self.fp.write(endrec)
  508.             self.fp.flush()
  509.         
  510.         if not self._filePassed:
  511.             self.fp.close()
  512.         
  513.         self.fp = None
  514.  
  515.  
  516.  
  517. class PyZipFile(ZipFile):
  518.     '''Class to create ZIP archives with Python library files and packages.'''
  519.     
  520.     def writepy(self, pathname, basename = ''):
  521.         '''Add all files from "pathname" to the ZIP archive.
  522.  
  523.         If pathname is a package directory, search the directory and
  524.         all package subdirectories recursively for all *.py and enter
  525.         the modules into the archive.  If pathname is a plain
  526.         directory, listdir *.py and enter all modules.  Else, pathname
  527.         must be a Python *.py file and the module will be put into the
  528.         archive.  Added modules are always module.pyo or module.pyc.
  529.         This method will compile the module.py into module.pyc if
  530.         necessary.
  531.         '''
  532.         (dir, name) = os.path.split(pathname)
  533.         if os.path.isdir(pathname):
  534.             initname = os.path.join(pathname, '__init__.py')
  535.             if os.path.isfile(initname):
  536.                 if basename:
  537.                     basename = '%s/%s' % (basename, name)
  538.                 else:
  539.                     basename = name
  540.                 if self.debug:
  541.                     print 'Adding package in', pathname, 'as', basename
  542.                 
  543.                 (fname, arcname) = self._get_codename(initname[0:-3], basename)
  544.                 if self.debug:
  545.                     print 'Adding', arcname
  546.                 
  547.                 self.write(fname, arcname)
  548.                 dirlist = os.listdir(pathname)
  549.                 dirlist.remove('__init__.py')
  550.                 for filename in dirlist:
  551.                     path = os.path.join(pathname, filename)
  552.                     (root, ext) = os.path.splitext(filename)
  553.                     if os.path.isdir(path):
  554.                         if os.path.isfile(os.path.join(path, '__init__.py')):
  555.                             self.writepy(path, basename)
  556.                         
  557.                     os.path.isfile(os.path.join(path, '__init__.py'))
  558.                     if ext == '.py':
  559.                         (fname, arcname) = self._get_codename(path[0:-3], basename)
  560.                         if self.debug:
  561.                             print 'Adding', arcname
  562.                         
  563.                         self.write(fname, arcname)
  564.                         continue
  565.                 
  566.             elif self.debug:
  567.                 print 'Adding files from directory', pathname
  568.             
  569.             for filename in os.listdir(pathname):
  570.                 path = os.path.join(pathname, filename)
  571.                 (root, ext) = os.path.splitext(filename)
  572.                 if ext == '.py':
  573.                     (fname, arcname) = self._get_codename(path[0:-3], basename)
  574.                     if self.debug:
  575.                         print 'Adding', arcname
  576.                     
  577.                     self.write(fname, arcname)
  578.                     continue
  579.             
  580.         elif pathname[-3:] != '.py':
  581.             raise RuntimeError, 'Files added with writepy() must end with ".py"'
  582.         
  583.         (fname, arcname) = self._get_codename(pathname[0:-3], basename)
  584.         if self.debug:
  585.             print 'Adding file', arcname
  586.         
  587.         self.write(fname, arcname)
  588.  
  589.     
  590.     def _get_codename(self, pathname, basename):
  591.         '''Return (filename, archivename) for the path.
  592.  
  593.         Given a module name path, return the correct file path and
  594.         archive name, compiling if necessary.  For example, given
  595.         /python/lib/string, return (/python/lib/string.pyc, string).
  596.         '''
  597.         file_py = pathname + '.py'
  598.         file_pyc = pathname + '.pyc'
  599.         file_pyo = pathname + '.pyo'
  600.         if os.path.isfile(file_pyo) and os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime:
  601.             fname = file_pyo
  602.         elif not os.path.isfile(file_pyc) or os.stat(file_pyc).st_mtime < os.stat(file_py).st_mtime:
  603.             import py_compile as py_compile
  604.             if self.debug:
  605.                 print 'Compiling', file_py
  606.             
  607.             
  608.             try:
  609.                 py_compile.compile(file_py, file_pyc, None, True)
  610.             except py_compile.PyCompileError:
  611.                 err = None
  612.                 print err.msg
  613.  
  614.             fname = file_pyc
  615.         else:
  616.             fname = file_pyc
  617.         archivename = os.path.split(fname)[1]
  618.         if basename:
  619.             archivename = '%s/%s' % (basename, archivename)
  620.         
  621.         return (fname, archivename)
  622.  
  623.  
  624.